package com.lulin.mall.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.lulin.common.constant.CartConstant;
import com.lulin.common.utils.R;
import com.lulin.common.vo.MemberVo;
import com.lulin.mall.cart.feign.ProductFeignService;
import com.lulin.mall.cart.interceptor.AuthInterceptor;
import com.lulin.mall.cart.service.ICartService;
import com.lulin.mall.cart.vo.Cart;
import com.lulin.mall.cart.vo.CartItem;
import com.lulin.mall.cart.vo.SkuInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * 购物车的实现类
 * 购物车信息是存在redis中的
 *
 * @author lulin
 * @date 2022/12/14 14:37
 */
@Service
public class CartServiceImpl implements ICartService {
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    ProductFeignService productFeignService;

    //线程池对象
    @Autowired
    ThreadPoolExecutor poolExecutor;

    /**
     * 查询当前登录用户的所有购物车信息
     */
    @Override
    public Cart getCartList() {
        //获取所有的购物车信息
        BoundHashOperations<String, Object, Object> operation = getCartKeyOperation();
        Set<Object> keys = operation.keys();
        //进行封装
        Cart cart = new Cart();
        ArrayList<CartItem> list = new ArrayList<>();
        for (Object k : keys) {
            String key = (String) k;
            Object o = operation.get(key);
            String json = (String) o;
            CartItem item = JSON.parseObject(json, CartItem.class);
            list.add(item);
        }
        //购物中存储的商品信息  List<CartItem>类型
        cart.setItems(list);

        return cart;
    }

    /**
     * 添加购物车
     *
     * @param skuId 商品sku编号
     * @param num   商品数量
     */
    @Override
    public CartItem addCart(Long skuId, Integer num) throws Exception {
        BoundHashOperations<String, Object, Object> hashOperations = getCartKeyOperation();

        //如果redis中存储了商品的信息，则只需更新商品的数量
        Object hashObj = hashOperations.get(skuId.toString());
        if (hashObj != null) {
            //说明 这个商品已经存在，就更新商品数量
            String str = (String) hashObj;
            CartItem item = JSON.parseObject(str, CartItem.class);
            item.setCount(item.getCount() + num);
            hashOperations.put(skuId.toString(), JSON.toJSONString(item));
            return item;
        }

        CartItem item = new CartItem();
        CompletableFuture skuInfoFuture = CompletableFuture.runAsync(() -> {
            //1、远程调用，根据skuId，获取商品信息
            R info = productFeignService.info(skuId);
            String skuInfoJSON = (String) info.get("skuInfoJSON");
            SkuInfoVo vo = JSON.parseObject(skuInfoJSON, SkuInfoVo.class);
            item.setCheck(true);//是否选中
            item.setCount(num);//购买的数量s
            item.setPrice(vo.getPrice());
            item.setImage(vo.getSkuDefaultImg());
            item.setSkuId(skuId);
            item.setTitle(vo.getSkuTitle());
            item.setSpuId(vo.getSpuId());
        }, poolExecutor);

        CompletableFuture saleAttrFuture = CompletableFuture.runAsync(() -> {
            //2、获取销售属性
            List<String> skuSaleAttrs = productFeignService.getSkuSaleAttrs(skuId);
            item.setSkuAttr(skuSaleAttrs);
        }, poolExecutor);

        //allOf：阻塞住，等待所有任务完成
        CompletableFuture.allOf(skuInfoFuture, saleAttrFuture).get();

        //3、保存到redis中
        String json = JSON.toJSONString(item);
        hashOperations.put(skuId.toString(), json);
        return item;
    }

    /**
     * 获取当前登录用户，购物车中的商品信息
     */
    @Override
    public List<CartItem> getUserCartItems() {
        BoundHashOperations<String, Object, Object> operation = getCartKeyOperation();
        List<Object> values = operation.values();
        List<CartItem> list = values.stream().map(item -> {
            String json = (String) item;
            CartItem cartItem = JSON.parseObject(json, CartItem.class);
            return cartItem;
        }).filter(item -> {
            return item.isCheck();
        }).collect(Collectors.toList());
        return list;
    }

    /**
     * 从session中拿到用户id，查redis查询数据
     */
    private BoundHashOperations<String, Object, Object> getCartKeyOperation() {
        //存储redis的是hash类型， cart:1   skuId：cartItem
        //拿到到当前登录的用户信息
        MemberVo memberVo = AuthInterceptor.threadLocal.get();
        String cartKey = CartConstant.CART_PREFIX + memberVo.getId();
        //通过key,查询redis中的数据
        BoundHashOperations<String, Object, Object> hashOperations = redisTemplate.boundHashOps(cartKey);
        return hashOperations;
    }
}
